import sys
import time
import openpyxl
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QMessageBox
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import sys
from PyQt6.QtWidgets import (QApplication, QMainWindow, QPushButton, QFileDialog, 
                           QVBoxLayout, QWidget, QDialog, QLabel, QDialogButtonBox,
                           QTextEdit)
from PyQt6.QtCore import Qt, QTimer
from selenium.webdriver.chrome.options import Options  # 添加这行
from PyQt6.QtWidgets import (QApplication, QMainWindow, QPushButton, QFileDialog, 
                           QVBoxLayout, QWidget, QDialog, QLabel, QDialogButtonBox,
                           QTextEdit, QMessageBox)
from PyQt6.QtCore import Qt, QTimer
from selenium import webdriver
from selenium.webdriver.chrome.options import Options  # 添加这行
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
# 全局变量，用于存储双击元素的XPATH和对应的值
xpath_list = []
value_list = []


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.is_checking = False  # 添加锁标志
        self.init_ui()

    def init_ui(self):
        layout = QVBoxLayout()

        start_button = QPushButton('Start')
        start_button.clicked.connect(self.start_process)

        layout.addWidget(start_button)
        self.setLayout(layout)

        self.setWindowTitle('My App')
        self.show()

    def start_process(self):
        # 打开Excel文件并读取URL
        file_name, _ = QFileDialog.getOpenFileName(
            self, "选择文件", "", "Text Files (*.txt)"        )
        if not file_name:
            return
        urls=[]  
        try:
            # 读取文本文件
            with open(file_name, 'r', encoding='utf-8') as file:
                urls = [line.strip() for line in file if line.strip()]
        # 启动Chrome浏览器驱动
            global driver
            driver = webdriver.Chrome()
            chrome_options = Options()
            chrome_options.add_argument('--ignore-certificate-errors')
            chrome_options.add_argument('--ignore-ssl-errors')
            
        # 启动Chrome浏览器
            driver = webdriver.Chrome(options=chrome_options)
            # driver.maximize_window()
            
            driver.get(urls[0])
            wait = WebDriverWait(driver, 10)  # 最多等10秒
            wait.until(
                EC.presence_of_element_located((By.TAG_NAME, "body"))
            )
            wait.until(
                lambda driver: driver.execute_script("return document.readyState") == "complete"
            )
            print("Page loaded successfully")

            # 注入JavaScript代码来监听双击事件，当双击发生时调用对应的Python函数（这里是个简单示意）
            driver.execute_script("""
                document.addEventListener('dblclick', function(event) {
                    window.pyObj.on_double_click(event.target);
                });
            """)
            # 这里可以添加更多监控网页的逻辑，比如等待页面加载完成等
            # time.sleep(2)
            self.monitor_webpage(driver)

            # driver.quit()       
        except Exception as e:
            print(f"Error: {e}")



    def monitor_webpage(self, driver):
        """监控网页元素"""
        try:
            # 注入基础 JavaScript 代码
            js_code = """
            // 重置全局变量
            window.lastElementInfo = null;
            
            // 获取元素的XPath
            function getXPath(element) {
                if (element.id !== '')
                    return `//*[@id="${element.id}"]`;
                    
                if (element === document.body)
                    return '/html/body';

                let path = '';
                while (element && element.nodeType === 1) {
                    let siblings = Array.from(element.parentNode.children).filter(
                        e => e.tagName === element.tagName
                    );
                    
                    if (siblings.length > 1) {
                        let index = siblings.indexOf(element) + 1;
                        path = `/${element.tagName.toLowerCase()}[${index}]${path}`;
                    } else {
                        path = `/${element.tagName.toLowerCase()}${path}`;
                    }
                    
                    element = element.parentNode;
                }
                return path;
            }

            // 处理元素点击
            function handleElementClick(element) {
                console.log('Element clicked:', element);
                let elementInfo = {
                    xpath: getXPath(element),
                    text: element.textContent.trim(),
                    href: element.href || '',
                    tagName: element.tagName.toLowerCase(),
                    value: element.value || ''
                };
                
                window.lastElementInfo = elementInfo;
                console.log('Set lastElementInfo:', elementInfo);
                return elementInfo;
            }

            // 移除旧的事件监听器（如果存在）
            if (window.oldListeners) {
                document.removeEventListener('click', window.oldListeners.click);
                document.removeEventListener('contextmenu', window.oldListeners.contextmenu);
                document.removeEventListener('mouseover', window.oldListeners.mouseover);
                document.removeEventListener('mouseout', window.oldListeners.mouseout);
            }

            // 存储新的事件监听器函数
            window.oldListeners = {
                click: function(e) {
                    console.log('Document click detected');
                    e.preventDefault();
                    e.stopPropagation();
                    handleElementClick(e.target);
                },
                contextmenu: function(e) {
                    console.log('Document right click detected');
                    e.preventDefault();
                    e.stopPropagation();
                    handleElementClick(e.target);
                },
                mouseover: function(e) {
                    e.target.style.outline = '4px solid red';
                },
                mouseout: function(e) {
                    e.target.style.outline = '';
                }
            };

            // 添加新的事件监听器
            document.addEventListener('click', window.oldListeners.click, true);
            document.addEventListener('contextmenu', window.oldListeners.contextmenu, true);
            document.addEventListener('mouseover', window.oldListeners.mouseover, true);
            document.addEventListener('mouseout', window.oldListeners.mouseout, true);

            // 监听浏览器的前进/后退事件
            window.onpopstate = function(event) {
                console.log('Navigation occurred');
                // 重新注入监听器
                setTimeout(function() {
                    document.addEventListener('click', window.oldListeners.click, true);
                    document.addEventListener('contextmenu', window.oldListeners.contextmenu, true);
                    document.addEventListener('mouseover', window.oldListeners.mouseover, true);
                    document.addEventListener('mouseout', window.oldListeners.mouseout, true);
                }, 100);
            };

            console.log('All event listeners have been added to document');
            """
            
            # 执行 JavaScript 代码
            driver.execute_script(js_code)
            print("JavaScript code injected successfully")

            # 设置定时器检查页面变化
            if hasattr(self, 'page_check_timer'):
                self.page_check_timer.stop()
            
            self.page_check_timer = QTimer()
            self.page_check_timer.timeout.connect(lambda: self.check_page_change(driver))
            self.page_check_timer.start(1000)  # 每秒检查一次

            # 设置定时器检查元素选择
            if hasattr(self, 'selection_timer'):
                self.selection_timer.stop()
            
            self.selection_timer = QTimer()
            self.selection_timer.timeout.connect(lambda: self.check_element_selected(driver))
            self.selection_timer.start(100)  # 每100ms检查一次
            
            print("Element selection monitoring started")

        except Exception as e:
            print(f"Error in monitor_webpage: {e}")

    def check_page_change(self, driver):
        """检查页面是否发生变化，如果变化则重新注入监听器"""
        try:
            needs_injection = driver.execute_script("""
                return !window.hasOwnProperty('oldListeners');
            """)
            
            if needs_injection:
                print("Page changed, reinjecting listeners...")
                self.monitor_webpage(driver)
                
        except Exception as e:
            print(f"Error checking page change: {e}")

    def check_element_selected(self, driver):
        # 如果正在检查，直接返回
        if self.is_checking:
            return
        
        try:
            # 设置锁
            self.is_checking = True
            # print("Checking for selected element...")  # 调试输出
            
            element_info = driver.execute_script("""
                let info = window.lastElementInfo;
                console.log('Current lastElementInfo:', info);
                
                if (info) {
                    // 确保获取所有需要的信息
                    return {
                        xpath: info.xpath || '',
                        text: info.text || '',
                        href: info.href || '',
                        tagName: info.tagName || '',
                        value: info.value || ''
                    };
                }
                return null;
            """)
            
            if element_info:
                print("Element selected:", element_info)
                if element_info.get('href'):
                    msg_box = QMessageBox()
                    msg_box.setWindowTitle("链接确认")
                    msg_box.setText(f"是否打开链接?\nURL: {element_info['href']}")
                    msg_box.setStandardButtons(
                        QMessageBox.StandardButton.Yes | 
                        QMessageBox.StandardButton.No
                    )
                    
                    if msg_box.exec() == QMessageBox.StandardButton.Yes:
                        current_url = driver.current_url
                        driver.get(element_info['href'])
                        self.wait_and_inject()
                else:
                    self.show_element_dialog(element_info['xpath'], element_info['text'])
                
        except Exception as e:
            print(f"Error checking element: {e}")
        finally:
            # 释放锁
            self.is_checking = False

    def show_element_dialog(self, xpath, text):
        msg_box = QMessageBox()
        msg_box.setWindowTitle("确认操作")
        msg_box.setText(f"元素值: {xpath}\nText: {text}")
        msg_box.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
        result = msg_box.exec()
        
        if result == QMessageBox.StandardButton.Yes:
            self.xpath_list.append(xpath)
            self.value_list.append(text)
    def on_double_click(self, element):
            xpath = self.get_xpath(element)
            xpath_list.append(xpath)
            msg_box = QMessageBox()
            msg_box.setWindowTitle("确认操作")
            msg_box.setText("确认获取元素值并继续吗？")
            msg_box.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
            result = msg_box.exec()
            if result == QMessageBox.StandardButton.Yes:
                value = element.text
                value_list.append(value)
            else:
                pass

    def get_xpath(self, element):
            try:
                return element.get_attribute('xpath')
            except:
                return ''

    def generate_process(self):
            # 执行流程，将获取的元素值写入另一个Excel
            output_workbook = openpyxl.Workbook()
            output_sheet = output_workbook.active

            for xpath, value in zip(xpath_list, value_list):
                output_sheet.append([xpath, value])

            output_workbook.save('output.xlsx')  # 替换为你的输出Excel文件名


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec())